/*
 * client_connection.c
 *
 *  Created on: 2012-4-30
 *      Author: jawinton
 */

#include "../apue.h"
#include <netdb.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MAXADDRLEN 256
#define BUFLEN 128

extern int connect_retry (int, const struct sockaddr *, socklen_t);

void print_uptime (int sockfd) {
	int n;
	char buf[BUFLEN];

	while ((n = recv(sockfd, buf, BUFLEN, 0)) > 0)
		write(STDOUT_FILENO, buf, BUFLEN);

	if (n < 0) err_sys("recv error");
}

int main (int argc, char *argv[]) {
	int sockfd, err;
	struct addrinfo *ailist, *aip;
	struct addrinfo hint;
	struct sockaddr_in *sinp;
	const char *addr;
	char abuf[INET_ADDRSTRLEN];

	if (argc != 3) err_quit("usage: ruptime hostname service");
	hint.ai_addr = NULL;
	hint.ai_addrlen = 0;
	hint.ai_canonname = NULL;
	hint.ai_family = 0;
	hint.ai_flags |= AI_CANONNAME;
	hint.ai_next = NULL;
	hint.ai_protocol = 0;
	hint.ai_socktype = SOCK_STREAM;
	//getaddrinfo的第二个参数需要在/etc/services中存在对应的端口号和协议
	if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0)
	//if ((err = getaddrinfo(argv[1], NULL, &hint, &ailist)) != 0)
		err_quit("getaddrinfo error: %s", gai_strerror(err));
	for (aip = ailist; aip != NULL; aip = ailist->ai_next) {
		if (aip->ai_family == AF_INET) {
			sinp = (struct sockaddr_in *)aip->ai_addr;
			addr = inet_ntop(aip->ai_family, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);
			printf(" address %s (%s)", addr?addr:"unknown", aip->ai_canonname);
			printf(" port %d", ntohs(sinp->sin_port));
		}
		printf("\n");
		if ( (sockfd = socket(aip->ai_family, SOCK_STREAM, 0)) < 0) err = errno;
		if ( connect_retry(sockfd, aip->ai_addr, aip->ai_addrlen) < 0) {
			err = errno;
		}
		else {
			print_uptime(sockfd);
			exit(0);
		}
	}
	fprintf(stderr, "cant't connect to %s: %s\n", argv[1], strerror(err));
	exit(1);
}
